package com.huas.service.serviceimpl;

import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeUtil;
import com.huas.constant.UserConstant;
import com.huas.dto.RoleMenuListDTO;
import com.huas.entity.LoginUser;
import com.huas.entity.Menu;
import com.huas.entity.User;
import com.huas.mapper.MenuMapper;
import com.huas.properties.JwtProperties;
import com.huas.service.MenuService;
import com.huas.utils.JwtUtil;
import com.huas.utils.RedisUtils;
import com.huas.utils.SecurityUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@Slf4j
public class MenuServiceImpl implements MenuService {
    @Resource
    private MenuMapper menuMapper;
    @Resource
    private UserDetailsServiceImpl userDetailsService;
    @Resource
    private RedisUtils redisUtils;
    @Resource
    private JwtProperties jwtProperties;

    /**
     * 获取权限列表
     */
    @Override
    public List<Tree<Integer>> selectMenuList() {
        /**
         * HuTool工具包，TreeUtil
         */
        List<Menu> list = menuMapper.selectMenuList();
        List<TreeNode<Integer>> collect = list.stream().map(getNodeFunction()).collect(Collectors.toList());
        List<Tree<Integer>> treeList = TreeUtil.build(collect, 0);
        return treeList;
    }

    /**
     * 修改权限列表
     */
    @Override
    @Transactional
    public String update(RoleMenuListDTO roleMenuListDTO) {
        //删除原有数据
        menuMapper.delete(roleMenuListDTO.getRoleId());
        //插入现有数据
        menuMapper.insert(roleMenuListDTO);
        /**
         * 解决修改用户权限后授权无法立即生效，需重新登录才能生效的bug
         */
        //获取当前用户
        User user = SecurityUtils.getLoginUser().getUser();
        //重新加载用户权限
        LoginUser loginUserNew = (LoginUser) userDetailsService.loadUserByUsername(user.getAccount());
        //获取用户id存入jwt
        Integer id = loginUserNew.getUser().getId();
        HashMap<String, Object> claims = new HashMap<>();
        claims.put(UserConstant.ACCOUNT_ID, id);
        //从redis更新用户信息
        redisUtils.set(UserConstant.LOGIN_MESSAGE + id, loginUserNew);
        log.info("用户信息已更新,key为{}", UserConstant.LOGIN_MESSAGE + id);
        //返回新的jwt令牌
        return JwtUtil.createJWT(
                jwtProperties.getAdminSecretKey(),
                jwtProperties.getAdminTtl(),
                claims);
    }

    private Function<Menu, TreeNode<Integer>> getNodeFunction() {
        return menu -> {
            TreeNode<Integer> node = new TreeNode<>();
            node.setId(menu.getId());
            node.setName(menu.getMenuName());
            node.setParentId(menu.getPid());
            node.setWeight(menu.getSort());
            return node;
        };
    }
}
